package multithreading;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 线程池
 *
 * Executor     接口
 * 定义了一个接收Runnable对象的方法executor，其方法签名为executor(Runnable command)，
 * 该方法接收一个Runnable实例，它用来执行一个任务，任务即一个实现了Runnable接口的类，
 * 一般来说，Runnable任务开辟在新线程中的使用方法为：new Thread(new RunnableTask())).start()，
 * 但在Executor中，可以使用Executor而不用显示地创建线程：executor.execute(new RunnableTask()); // 异步执行
 *
 *
 * ExecutorService      是Executor的子接口，比Executor使用更广泛
 * ExecutorService提供了两种关闭执行器的方法
 *     shutdown()       在shutdown()执行程序服务上调用方法时，它将停止接受新任务，等待先前提交的任务执行，然后终止执行程序
 *     shutdownNow()    此方法中断正在运行的任务并立即关闭执行程序
 *
 *
 *
 * Executors 类
 *
 * Executors类生成ExecutorService实例的静态方法
 *
 * public static ExecutorService newSingleThreadExecutor()      创建只有一个工作线程的线程池
 * public static ExecutorService newScheduledThreadScheduledExecutor()      创建只有一个工作线程的线程池，
 *                                                                          能按时间计划来执行任务
 *
 * public static ScheduledExecutorService newCachedThreadPool()     有任务时才创建新线程，空闲线程额被保留60s后关闭
 *                      缓存型池子，先查看池中有没有以前建立的线程，如果有，就reuse（重用）.如果没有，就建一个新的线程加入池中。
 *                      缓存型池子通常用于执行一些生存期很短的异步型任务，因此在一些面向连接的daemon型SERVER中用得不多。
 *                      但对于生存期短的异步任务，它是Executor的首选。
 *                      能reuse的线程，必须是timeout IDLE内的池中线程，缺省timeout是60s，超过这个IDLE时长，线程实例将被终止及移出池。
 *                      注意，放入CachedThreadPool的线程不必担心其结束，超过TIMEOUT不活动，其会自动被终止
 *
 * public static ExecutorService newFixedThreadPool(int nThreads)   创建固定数目的线程池，空闲线程会被一直保留，
 *                                                                  参数nThreads表示线程池总线程的数目
 *                                                                  与cacheThreadPool差不多，也是能reuse就用
 *
 * public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
 *                      创建一个含有corePoolSize个工作线程的线程池，
 *                      并且线程池能按时间计划来执行任务（周期执行），允许用户设定计划执行任务的时间，
 *                      参数corePoolSize表示线程池中线程的最小数目，当任务较多时，线程池可能会创建更多的工作线程来执行任务
 *
 *
 *
 * */
public class ExecutorDemo {
    static int k = 1;
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(5);  // 创建固定有5个工作线程的线程池
        for (int i = 1; i <= 50; i++) {
            executorService.execute(new Runnable() {

                @Override
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("任务" + ExecutorDemo.k++);
                }
            });
        }
        executorService.execute(() -> System.out.println("最终任务"));
        executorService.shutdown();
//        executorService.shutdownNow();
    }
}
